package com.hd.manager.task;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hd.appcommon.entity.Course;
import com.hd.appcommon.service.CourseService;
import com.hd.appcommon.utils.HzieeAPIUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

@Component
@Slf4j
public class CourseSync {

    @Autowired
    CourseService courseService;
    @Autowired
    ExecutorUtil executorUtil;
    @Autowired
    HzieeAPIUtils hzieeAPIUtils;
    public List<Course> courseList = new ArrayList<>();
    public int lock = -1;

    /**
     * 获取排课信息
     * year:学年（2021-2022）
     * term：学期（1、2）
     */
    public void getCourseArrangeMsg(String year, String term) {

        Integer page = 1;
        Integer size = 100;
        //第一次请求，获取页数、总数据条数
        JSONObject data_pages = hzieeAPIUtils.requestCourseArrangement(year, term, page, size);
        Integer pages = data_pages.getObject("pages", int.class);
        Integer total = data_pages.getObject("total", int.class);
        log.info("总数据条数:{},总页数:{}",total,pages);

        //使用多线程获取分页信息
        for (page = 0; page <= pages; page++) {
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                log.error("do something error: ", e);
            }
            log.info("*************开始获取{}页",page);
            executorUtil.addCourse(year, term, page, size);
        }

        //等待所有的线程运行完成
        // 获取的数据条数与总数相等
        while (total > courseList.size()) {
            System.out.println("size:" + courseList.size());
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                log.error("do something error: ", e);
            }
        }

        //List里的对象按照对象的属性去重
        courseList = courseList.stream().collect(Collectors
                .collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Course::getCourCode))),
                        ArrayList::new));

        //将数据库中已经存在相同code的课程去除，只增加不同的code的课程
        List<String> courseCodeList = courseList.stream().map(Course::getCourCode).collect(Collectors.toList());
        //取出重复的课程的课程号
        List<Course> courseList_repeat = courseService.list(new QueryWrapper<Course>().in("cour_code",courseCodeList));
        List<String> courseCodeList_repeat = courseList_repeat.stream().map(Course::getCourCode).collect(Collectors.toList());
        //将重复的课程号从待插入的list中删除
        //即只保留不存在于”重复课程号列表“中的记录
        courseList = courseList.stream().filter(
                        i -> !courseCodeList_repeat.contains(i.getCourCode()))
                .collect(Collectors.toList());

        courseService.saveBatch(courseList);

        log.info("插入{}学期课程数据{}条",year+"-"+term,courseList.size());


    }



    //将课程json数据转换为Course
    public Course getCourse(JSONObject item) {
        Course course = new Course();
        try {
            course.setCourName(item.getString("KCMC"));
            course.setCourCode(item.getString("KCH"));
            course.setCourCredit(item.getFloat("XF"));
            course.setCourCollege(item.getString("KKYXMC"));
            course.setCourTeaName(item.getString("JSXM"));
            course.setCourType(item.getString("KCXZMC"));
            course.setCourAttr(item.getString("KCSXMC"));
            course.setCourCodeSpecific(item.getString("KCXKH"));
        } catch (Exception e) {
            log.error("解析课程数据出错");
            e.printStackTrace();
        }
        return course;
    }



    //实现多线程的辅助内部类
    @Component
    class ExecutorUtil {
        @Async("asyncServiceExecutor")
        public void addCourse(String year, String term, Integer page, Integer size) {
            JSONObject data = hzieeAPIUtils.requestCourseArrangement( year, term, page, size);
            //请求失败等待两秒重新请求
            if (data == null){
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    log.error("do something error: ", e);
                }
                executorUtil.addCourse( year, term, page, size);
                return;
            }else{
                log.info("请求排课信息成功:{},{},{},{}",year, term, page, size);
            }


            JSONArray records = data.getJSONArray("records");
            if (records.size()==0){
                log.error("records长度为0");
                return;
            }
            List<Course> courseListTem = new ArrayList<>();
            for (int i = 0; i < records.size(); i++) {
                JSONObject item = records.getJSONObject(i);
                courseListTem.add(getCourse(item));
            }

            while (lock == -1){
                lock = page;
                if (lock != page) continue;
//                log.info("++++++++++++++++开始插入第{}页的内容                                {}",page,page);
                courseList.addAll(courseListTem);
//                for (int i = 0; i < records.size(); i++) {
//                    JSONObject item = records.getJSONObject(i);
//                    courseList.add(getCourse(item));
//                }
//                System.out.println("size:" + courseList.size());
//                log.info("countPage:{}",countPage++);
                log.info("结束插入第{}页的内容，listSize：{}",page,courseList.size(),page);
                lock = -1;
                break;
            }
        }

    }
}
